import { Draw } from "../Draw/Draw";
import { IKeyMap, VoidFun } from "../Interface/Pptx";
import { getContentMenuTemp } from "../Template/ContentMenuTemp";

/**
 * 右键菜单
 */
export class ContextMenu {
  private draw: Draw;
  constructor(draw: Draw) {
    this.draw = draw;
  }

  // 提供 show 显示菜单方法
  public show(e: MouseEvent, menuType: "stage" | "group") {
    const root = this.draw.getRootBox();

    const menu = document.createElement("div");
    menu.className = "konva-root-container-contextmenu";
    menu.innerHTML = getContentMenuTemp(menuType);

    menu.addEventListener("click", (e) => e.stopPropagation());
    // 为了关闭，应该创建 menu mask
    this.draw.getMenuMask().createMask();

    // 菜单只能加在 konvajs-content 下
    const parent = <HTMLElement>root.querySelector(".konvajs-content");
    parent.appendChild(menu);

    // 初始化事件 - 以实现右键菜单事件
    this.contextmenuEventHandle(menu);

    /**
     * 做位置纠正
     *  1. 菜单超出边界，则需要纠正
     *  2. 二级菜单超出边界，则需要纠正
     */

    // 获取 parent 宽高
    const { clientWidth, clientHeight } = parent;
    // 当前响应的元素的绝对坐标
    const { offsetX, offsetY } = e;
    // 右键菜单的宽高
    const menuHeight = menu.clientHeight;
    const menuWidth = menu.clientWidth;

    let top = offsetY;
    let left = offsetX;

    if (offsetY + menuHeight > clientHeight) top = offsetY - menuHeight;
    if (offsetY - menuHeight < 0) top = 0;
    if (offsetX + menuWidth > clientWidth) left = offsetX - menuWidth;
    if (offsetX - menuWidth < 0) left = 0;

    menu.style.top = top + "px";
    menu.style.left = left + "px";

    // 还需要纠正右键菜单二级
    if (left + menuWidth + 180 > clientWidth) {
      const submenu = menu.querySelectorAll(".submenu");
      const submenulist = <NodeListOf<HTMLDivElement>>submenu;
      submenulist.forEach((subItem) => {
        const transform = "translateX(calc(-200% + 20px))  translateY(-50%)";
        subItem.style.transform = transform;
      });
    }
  }

  // 右键菜单响应事件
  private contextmenuEventHandle(menu: HTMLDivElement) {
    const command = this.draw.getCommand();
    const eventMap: IKeyMap<string, VoidFun> = {
      cut: command.executeCut, // 剪切
      copy: command.executeCopy, // 复制
      paste: command.executePaste, // 粘贴
      settings: command.executeOpenSetting, // 设置属性
      preview: command.executePreviewCurrent, // 预览当前
    };
    const menulist = menu.querySelectorAll("[data-contextmenu]");
    const menulistArray = <NodeListOf<HTMLElement>>menulist;

    menulistArray.forEach((menuItem) => {
      const menuType = menuItem.dataset.contextmenu!;
      menuItem.addEventListener("click", (e) => {
        // 点击菜单后，需要关闭菜单、关闭蒙版 - 这里的顺序不能乱哈，一定先执行这个，后执行具体的操作，不然蒙版会一直隐藏，功能无法实现
        this.draw.getMenuMask().removeMask();
        if (menuType && eventMap[menuType]) eventMap[menuType]();
        e.stopPropagation();
        e.preventDefault();
      });
    });
  }
}
